package com.xishu.controller;

import com.xishu.annotation.valid.MethodValidator;
import com.xishu.entity.NameAndId;
import com.xishu.entity.shop.*;
import com.xishu.response.ResponseData;
import com.xishu.response.ResponseStatus;
import com.xishu.response.VerifyUtil;
import com.xishu.service.*;
import com.xishu.util.Tools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Api(description = "场景管理")
@RestController
public class SceneController implements Tools {
    private static Logger logger = LoggerFactory.getLogger(SceneController.class);

    private CommonService commonService = CommonService.getInstance();
    private FoodTableService foodTableService = FoodTableService.getInstance();
    private SceneService sceneService = SceneService.getInstance();

    @ApiOperation(value = "创建场景")
    @PostMapping(value = ("/user/scene"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true, checkShopId = true)
    public ResponseData create(@RequestBody Scene scene) throws Exception {
        VerifyUtil.verify(() -> isNotEmpty(isNotEmpty(scene.getShopId())));
        VerifyUtil.verify(() -> isNotEmpty(scene.getTimeConfigList()));
        VerifyUtil.verify(() -> isNotEmpty(scene.getName()));

        Long shopId = scene.getShopId();
        Shop shop = ShopService.getInstance().findShopById(scene.getShopId());
        scene.setShopName(shop.getName());

        List<Scene> sceneList = ShopService.getInstance().findSceneList(shopId);
        List<SceneTimeConfig> sceneTimeConfigList = sceneList.stream().flatMap(p -> getList(p.getTimeConfigList()).stream()).collect(Collectors.toList());

        for (SceneTimeConfig sceneTimeConfig : scene.getTimeConfigList()) {
            SceneService.getInstance().isTimeConfigValid(sceneTimeConfig);
            VerifyUtil.verify(() -> !SceneService.getInstance().isTimeConfigCheckWithInteger(sceneTimeConfig, sceneTimeConfigList), ResponseStatus.SCENE_TIME_CONFLICT);
        }

        if (scene.getFoodTableConfigId() != null) {
            FoodTableConfig foodTableConfig = commonService.findEntity(scene.getFoodTableConfigId(), FoodTableConfig.class);
            scene.setFoodTableConfigIndex(foodTableConfig.getShowIndex());
        }

        sceneService.checkRunModule(scene);

        ResponseData responseData = CommonService.getInstance().createObject(scene, sceneRequest -> {
            if (scene.getFoodTableConfigId() != null) {
                try {
                    FoodTableConfig foodTableConfig = commonService.findEntity(scene.getFoodTableConfigId(), FoodTableConfig.class);
                    foodTableService.syncFoodTableConfigToScene(foodTableConfig, scene.getId());
                } catch (Exception e) {
                    logger.error("e", e);
                }
            }
        }, true, ResponseStatus.SCENE_NAME_EXIST);

        //刷新缓存
        sceneService.putCache(shopId);

        return responseData;
    }

    @ApiOperation(value = "修改场景")
    @PutMapping(value = ("/user/scene/modify"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShop = true)
    public ResponseData modify(@RequestBody Scene scene) throws Exception {
        Long id = scene.getId();
        Scene sceneInDb = commonService.findEntity(id, Scene.class);
        Long foodTableConfigIdInDb = sceneInDb.getFoodTableConfigId();
        List<Scene> sceneList = ShopService.getInstance().findSceneList(sceneInDb.getShopId());
        //过滤其它场景
        List<Scene> otherSceneList = sceneList.stream().filter(p -> !equals(p.getId(), scene.getId())).collect(Collectors.toList());
        List<SceneTimeConfig> sceneTimeConfigList = otherSceneList.stream().flatMap(p -> getList(p.getTimeConfigList()).stream()).collect(Collectors.toList());

        if (scene.getTimeConfigList() != null) {
            for (SceneTimeConfig sceneTimeConfig : scene.getTimeConfigList()) {
                SceneService.getInstance().isTimeConfigValid(sceneTimeConfig);
                VerifyUtil.verify(() -> !SceneService.getInstance().isTimeConfigCheckWithInteger(sceneTimeConfig, sceneTimeConfigList), ResponseStatus.SCENE_TIME_CONFLICT);
            }
        }

        if (scene.getFoodTableConfigId() != null) {
            FoodTableConfig foodTableConfig = commonService.findEntity(scene.getFoodTableConfigId(), FoodTableConfig.class);
            scene.setFoodTableConfigIndex(foodTableConfig.getShowIndex());
        }

        sceneService.syncToModifyInB(scene);
        sceneService.checkRunModule(scene);
        sceneService.syncToCatalogName(scene);
        sceneService.syncToItemPriceConfig(scene);
        sceneService.syncToSuggestionItem(scene);

        ResponseData responseData = CommonService.getInstance().updateObject(scene, scene1 -> {
            //传了餐桌配置，并且餐桌配置不同
            if (scene.getFoodTableConfigId() != null && !equals(scene1.getFoodTableConfigId(), foodTableConfigIdInDb)) {
                try {
                    //删除历史餐桌
                    {
                        Long shopId = sceneInDb.getShopId();
                        FoodTable foodTable = new FoodTable();
                        foodTable.setShopId(shopId);
                        foodTable.setSceneId(sceneInDb.getId());
                        foodTable.setBeRequest(true);
                        commonService.delete(foodTable);
                    }

                    FoodTableConfig foodTableConfig = commonService.findEntity(scene.getFoodTableConfigId(), FoodTableConfig.class);
                    logger.info("will sync to food table config {}", foodTableConfig.getId());
                    foodTableService.syncFoodTableConfigToScene(foodTableConfig, scene.getId());
                } catch (Exception e) {
                    logger.error("e", e);
                }
            }
        }, null, ResponseStatus.SCENE_NAME_EXIST);

        //清空缓存，刷新缓存
        sceneService.putCache(sceneInDb.getShopId());

        return responseData;
    }

    @ApiOperation(value = "查询场景")
    @PutMapping(value = ("/user/scene"), produces = ("application/json;charset=UTF-8"))
    public ResponseData search(@RequestBody Scene scene) throws Exception {
        return CommonService.getInstance().searchResponse(scene, (s) -> {
            try {
                Long shopId = s.getShopId();
                Shop shop = ShopService.getInstance().findShopById(shopId);
                s.setShopName_zh(shop.getName_zh());
                s.setShopName_en(shop.getName_en());

                //默认将落单审核关闭
                getList(s.getRunModuleSceneList()).forEach(p -> {
                    //默认不审核
                    if (p.getSendToKitchenAuditPayAfter() == null) {
                        p.setSendToKitchenAuditPayAfter(false);
                    }
                });
            } catch (Exception e) {
                logger.error("e", e);
            }
        });
    }

    @ApiOperation(value = "删除场景")
    @DeleteMapping(value = ("/user/scene"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(checkShopId = true)
    public ResponseData delete(@RequestBody Scene scene) throws Exception {
        Long shopId = null;
        if (scene.getId() != null) {
            Scene sceneInDb = commonService.findEntity(scene.id, Scene.class);
            shopId = sceneInDb.getShopId();
        }

        //删除使用了场景的品类

        Scene sceneInDb = SceneService.getInstance().findScene(scene.getId());

        List<Catalog> catalogByShopId = CatalogService.getInstance().findCatalogByShopId(sceneInDb.getShopId());

        for (Catalog catalog : catalogByShopId) {
            //品类
            List<NameAndId> catalogNameAndIdList = catalog.getSceneList().stream().filter(s -> !equals(s.getId(), scene.getId())).collect(Collectors.toList());
            catalog.setSceneList(catalogNameAndIdList);
            commonService.save(catalog);
            //菜和套餐的处理
            List<Item> itemByCatalogId = ItemService.getInstance().findItemByCatalogId(catalog.getId(), true);
            for (Item item : itemByCatalogId) {
                //场景
               if (isNotEmpty(item.getSceneList())){
                   List<NameAndId> itemNameAndIdList = item.getSceneList().stream().filter(s -> !equals(s.getId(), scene.getId())).collect(Collectors.toList());
                   catalog.setSceneList(itemNameAndIdList);
               }
                //场景价格
                if (isNotEmpty(item.getPriceConfigList())){
                    List<PriceConfig> priceConfigList = item.getPriceConfigList().stream().filter(s -> !equals(s.getSceneId(), scene.getId())).collect(Collectors.toList());
                    item.setPriceConfigList(priceConfigList);
                }
                commonService.save(item);
            }

        }

        //删除优惠券中的场景
        DiscountTicket discountTicket = new DiscountTicket();
        discountTicket.setCompanyId(sceneInDb.getCompanyId());
        discountTicket.setEntity(true);
        try {
            commonService.doAll(discountTicket, c -> {
                try {
                    if (isNotEmpty(c.getSceneList())) {
                        List<NameAndId> tickeNameAndIdList = c.getSceneList().stream().filter(s -> !equals(s.getId(), scene.getId())).collect(Collectors.toList());
                        c.setSceneList(tickeNameAndIdList);
                    }
                    commonService.save(c);
                } catch (Exception e) {
                    logger.error("e", e);
                }

            });

        } catch (Exception e) {
            logger.error("e", e);
        }

        ResponseData responseData = CommonService.getInstance().delete(scene);

        if (shopId != null) {
            //刷新缓存
            sceneService.putCache(shopId);
        }

        return responseData;
    }

    @ApiOperation(value = "查询当前哪一个场景正在适合,传shopId")
    @PutMapping(value = ("/user/scene/ok"), produces = ("application/json;charset=UTF-8"))
    @MethodValidator(mustLogin = false)
    public ResponseData okScene(@RequestBody Scene reqScene) throws Exception {
        Optional<Scene> sceneOptional = SceneService.getInstance().findSceneOptional(reqScene.getShopId());
        if (!sceneOptional.isPresent()) {
            Scene scene = new Scene();
            CommonService.getInstance().dealDefaultValueWithAnnotation(scene);
            return commonService.createResponse(scene);
        } else {
            return commonService.createResponse(sceneOptional.get());
        }
    }
}
